package com.uatair.common.mqtt.uploader;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import com.uatair.common.enums.SuNongYunApi;
import com.uatair.common.mqtt.domain.DroneResponse;
import com.uatair.common.mqtt.domain.dto.ApiUploadResponse;
import com.uatair.common.mqtt.domain.task.RecodeTask;
import com.uatair.common.mqtt.domain.task.SortieTask;
import com.uatair.common.mqtt.domain.task.TaskDTO;
import com.uatair.common.mqtt.domain.task.UavTask;
import com.uatair.common.mqtt.util.AESUtil;
import com.uatair.common.mqtt.util.UAesUtil;
import com.uatair.common.utils.StringUtils;
import com.uatair.common.utils.http.HttpUtils;
import com.uatair.common.utils.ip.AddressUtils;
import okhttp3.*;
import org.json.JSONArray;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;

@Component
public class SuNongYunTaskUploader {

    private static final Logger log = LoggerFactory.getLogger(SuNongYunTaskUploader.class);

    private static String TOKEN;
    public static String API_URL = "https://jhl.jssny.com.cn/api_portal/portal/uav";
    public SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    public SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd");

    public static void main(String[] args) throws IOException {
        getSuNongYunToken();
        // 现在你可以使用clientToken了
//        System.out.println("Client Token: " + TOKEN);
//        uploadRegister(droneResponse);
//        uploadDronePosition(droneResponse);
//        uploadJobInformation(droneResponse);
//        uploadJobLand(droneResponse);
//        uploadDroneTrace(droneResponse);
//        uploadJobImage(droneResponse);

        // 示例用法
//        List<List<Double>> polygons = generatePolygon(
//                120.5650563,
//                41.155284,
//                "2025-06-16 17:35:40",
//                "2025-06-16 17:39:31",
//                5 // 0.5公里半径
//        );
//
//        // 输出结果
//        System.out.println(polygons.toString());
    }

    public static void getSuNongYunToken() throws IOException {
        String body = "{\r\n   \"username\": \"4400004403006\",\r\n   \"password\": \"F5~!EwsfFdrQQyzo\"\r\n}";
        JSONObject requestBody = new JSONObject(body);
        Response post = HttpUtils.getPost(requestBody, API_URL + "/accessToken");

        String responseBody = post.body().string();
        JSONObject responseJson = new JSONObject(responseBody);
        log.info("更新苏农云token： {}", responseBody);
        TOKEN = responseJson.getString("data");
    }

    public List<RecodeTask> putSuNongYunTask(TaskDTO taskDTO) {
        List<UavTask> uavTaskList = taskDTO.getUavTaskList();
        List<SortieTask> sortieTaskList = taskDTO.getSortieTaskList();
        List<RecodeTask> recodeTaskList = new ArrayList<>();
        for (UavTask uavTask : uavTaskList) {
            ZhiBaoYunTaskUploader zhiBaoYunTaskUploader = new ZhiBaoYunTaskUploader();
            DroneResponse drone = zhiBaoYunTaskUploader.getDrone(uavTask.getSn(), 1);
            if (drone!=null) {
                RecodeTask recodeRegister = uploadRegister(drone, uavTask);
                RecodeTask recodeDrone = uploadDronePosition(drone);
                ZhiBaoYunTaskUploader.setTaskId(taskDTO, recodeTaskList, recodeRegister);
                ZhiBaoYunTaskUploader.setTaskId(taskDTO, recodeTaskList, recodeDrone);
            }
        }
        for (SortieTask sortieTask : sortieTaskList) {
            List<String> strings = UAesUtil.downloadAndParseFile(sortieTask.getPath());
            if (StringUtils.isNotEmpty(strings)) {
                RecodeTask recodeJobInfo = uploadJobInformation(sortieTask, strings);
                RecodeTask recodeJobLand = uploadJobLand(sortieTask);
                RecodeTask recodeTrace = uploadDroneTrace(sortieTask, strings);
                ZhiBaoYunTaskUploader.setTaskId(taskDTO, recodeTaskList, recodeJobInfo);
                ZhiBaoYunTaskUploader.setTaskId(taskDTO, recodeTaskList, recodeJobLand);
                ZhiBaoYunTaskUploader.setTaskId(taskDTO, recodeTaskList, recodeTrace);
            }
        }
        return recodeTaskList;
    }

    //7.2 无人机基本信息上报
    public RecodeTask uploadRegister(DroneResponse droneResponse, UavTask uavTask) {
        try {
            if ("0".equals(uavTask.getStatus())) {
                // 构建JSON对象
                JSONObject droneInfo = new JSONObject();
                droneInfo.put("droneId", droneResponse.getDroneId());
                droneInfo.put("droneSn", "18928362"+droneResponse.getDroneId());//飞控编码 未返回
                droneInfo.put("droneType", droneResponse.getDroneType());
                droneInfo.put("droneModel", "3WWDZ-U50C");//droneResponse.getDroneModel()
                droneInfo.put("swVersion", "5.6.5");
                droneInfo.put("hwVersion", "1.3.9");
                droneInfo.put("droneOwnerTpye", "1");
                droneInfo.put("orgName", "LHFJ");

                JSONObject servOrgDroneInfo = new JSONObject();
                servOrgDroneInfo.put("servOrgCode", "31165812-5");
                servOrgDroneInfo.put("servOrgName", "东台联合飞机科技有限公司");
                servOrgDroneInfo.put("servOrgShortName", "联合飞机");
                servOrgDroneInfo.put("servOrgCode", "518116");
                servOrgDroneInfo.put("servOrgAddress", "");
                servOrgDroneInfo.put("servOrgPrincName", "杨二闯");
                servOrgDroneInfo.put("servOrgPrincPhone", "18827542526");
                servOrgDroneInfo.put("servOrgDronePilotID", "");
                servOrgDroneInfo.put("servOrgDronePilotName", "");
                servOrgDroneInfo.put("dronePltCertImgLen", 1);
                servOrgDroneInfo.put("dronePltCertImgCtx", "0");
                if ("672339203207".equals(droneResponse.getDroneId())) {
                    droneInfo.put("orgName", "SZLF");
                    servOrgDroneInfo.put("servOrgName", "深圳联合飞机科技有限公司");
                }
                droneInfo.put("servOrgDroneInfo", servOrgDroneInfo);

                JSONObject privDroneInfo = new JSONObject();
                privDroneInfo.put("privDroneOwnerName", "");
                privDroneInfo.put("isOwnerDronePilot", "");
                privDroneInfo.put("privDronePilotId", "");
                privDroneInfo.put("privDronePilotName", "");
                droneInfo.put("privDroneInfo", privDroneInfo);

                JSONArray drones = new JSONArray();
                drones.put(droneInfo);
                JSONObject requestBody = new JSONObject();
                requestBody.put("droneInfo", drones);
                ApiUploadResponse apiUploadResponse = commonUpload(requestBody, SuNongYunApi.REGISTER.url, "672339203207".equals(droneResponse.getDroneId()));
                return ZhiBaoYunTaskUploader.getRecode(apiUploadResponse, requestBody, "无人机基本信息上报");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    //7.3位置信息推送接口
    public RecodeTask uploadDronePosition(DroneResponse droneResponse) {
        try {
            if (droneResponse.getOsd()!=null) {
                if (droneResponse.getOsd().getLongitude() > 0) {
                    // 构建请求体
                    JSONObject droneState = new JSONObject();
                    droneState.put("totalV", 72.30);
                    droneState.put("totalI", 13.15);
                    droneState.put("pumpSpeed", 0);
                    droneState.put("residualDosage", 8.61);
                    droneState.put("batSoc", 84.2);
                    JSONObject dronePositionInfo = new JSONObject();
                    dronePositionInfo.put("droneId", droneResponse.getDroneId());
                    dronePositionInfo.put("orgName", "LHFJ");
                    if ("672339203207".equals(droneResponse.getDroneId()))
                        dronePositionInfo.put("orgName", "SZLF");
                    String currentTime = sdf.format(new Date());
                    dronePositionInfo.put("sTime", currentTime);
                    dronePositionInfo.put("pTime", currentTime);
                    dronePositionInfo.put("isWork", 0);
                    dronePositionInfo.put("jobType", 2);
                    dronePositionInfo.put("cropsType", 0);
                    dronePositionInfo.put("lon", droneResponse.getOsd().getLongitude());
                    dronePositionInfo.put("lat", droneResponse.getOsd().getLatitude());
                    dronePositionInfo.put("jobWidth", 3);
                    dronePositionInfo.put("heightSea", droneResponse.getOsd().getHeight());
                    dronePositionInfo.put("heading", droneResponse.getOsd().getHeading());
                    dronePositionInfo.put("velh", droneResponse.getOsd().getGs());
                    dronePositionInfo.put("velup", droneResponse.getOsd().getVs());
                    dronePositionInfo.put("heightCrop", droneResponse.getOsd().getAltitude());
                    dronePositionInfo.put("possatNum", 0);
                    dronePositionInfo.put("headsatNum", 0);
                    dronePositionInfo.put("usesatNum", 0);
                    dronePositionInfo.put("vissatNum", 0);
                    dronePositionInfo.put("hdop", 0);
                    dronePositionInfo.put("droneState", droneState);
                    JSONArray drones = new JSONArray();
                    drones.put(dronePositionInfo);

                    JSONObject requestBody = new JSONObject();
                    requestBody.put("dronePositionInfo", drones);
                    ApiUploadResponse apiUploadResponse = commonUpload(requestBody, SuNongYunApi.POSITION.url, "672339203207".equals(droneResponse.getDroneId()));
                    return ZhiBaoYunTaskUploader.getRecode(apiUploadResponse, requestBody, "位置信息推送接口");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("位置信息接口调用失败: ", e);
        }
        return null;
    }

    //7.4作业信息推送接口
    public RecodeTask uploadJobInformation(SortieTask sortieTask, List<String> strings) {
        try {
            if (!StringUtils.isEmpty(strings)) {
                // 1. 创建最内层的 workInfo JSON 对象
                JSONObject workInfo = new JSONObject();
                workInfo.put("droneId", sortieTask.getSn());
                workInfo.put("flySorties", sortieTask.getSortieNo());
                workInfo.put("missionType", "0".equals(sortieTask.getOptMode()) ? "01" : "02");
                workInfo.put("cropType", "00");
                workInfo.put("cropPhase", "00");
                workInfo.put("areaCode", "");
                workInfo.put("missionArea", sortieTask.getSize()*0.0015);
                workInfo.put("jobHour", sortieTask.getFlightTime()/1000/60/60);
                workInfo.put("jobAreaNg", 0);
                workInfo.put("passedArea", sortieTask.getSize()*0.0015);
                workInfo.put("sprayWidth", sortieTask.getLineSpacing());
                workInfo.put("pumpspeed", 0);
                workInfo.put("pesticideNums", 0);
                workInfo.put("prayAmount", sortieTask.getDosageOfKg());
                workInfo.put("flyBeginTime", sdf.format(sortieTask.getStartTime()));
                workInfo.put("flyEndTime", sdf.format(sortieTask.getEndTime()));
                workInfo.put("executionTime", sdf.format(sortieTask.getStartTime()));
                workInfo.put("mileage", sortieTask.getFlightDistance());
//                List<double[]> doubles = generateDronePath(sortieTask.getGeoJson(),sortieTask.getStartTime(),sortieTask.getEndTime());
                List<JSONObject> traceJson = AESUtil.getJsonObjects(strings);
                LocalDateTime startTime = sortieTask.getStartTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
                LocalDateTime endTime = sortieTask.getEndTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
                long totalMillis = Duration.between(startTime, endTime).toMillis();
                double intervalMillis = (double) totalMillis / ((traceJson.size()==1?2:traceJson.size()) - 1);
                List<double[]> coordinates = new ArrayList<>();
                for (int i = 0; i < traceJson.size(); i++) {
                    JSONObject osd = traceJson.get(i);
                    // 计算当前时间点
                    LocalDateTime currentTime = startTime.plus(Math.round(i * intervalMillis), ChronoUnit.MILLIS);
                    // 确保最后一个时间点不超过 endTime
                    if (currentTime.isAfter(endTime)) {
                        currentTime = endTime;
                    }
                    double lon = osd.getDouble("lon");
                    double lat = osd.getDouble("lat");
                    coordinates.add(new double[]{lon, lat, currentTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()});
                }
                if (!coordinates.isEmpty()) {
                    workInfo.put("center", "MULTIPOINT ((" + coordinates.get(coordinates.size()/2)[0] + " " + coordinates.get(coordinates.size()/2)[1] + "))");
                    workInfo.put("longitude", coordinates.get(0)[0]);
                    workInfo.put("latitude", coordinates.get(0)[1]);
                    Gson gson = new Gson();
                    workInfo.put("trace", gson.toJson(coordinates));
                }
                workInfo.put("acrossDistrict", 0);
                if (StringUtils.isNotEmpty(sortieTask.getPositionInfo())) {
                    Map<String, String> map = AddressUtils.parseChineseAddress(sortieTask.getPositionInfo());
                    workInfo.put("locProvince", map.getOrDefault("province", "江苏省"));
                    workInfo.put("locCity", map.getOrDefault("city", "盐城市"));
                    workInfo.put("locCounty", map.getOrDefault("country", "东台市"));
                    workInfo.put("locTown", map.getOrDefault("town", "东台镇"));
                }
                workInfo.put("workModeValue", 1);
                JSONArray works = new JSONArray();
                works.put(workInfo);
                // 2. 创建最外层的 JSON 对象
                JSONObject requestBody = new JSONObject();
                requestBody.put("workInfo", works);
                ApiUploadResponse apiUploadResponse = commonUpload(requestBody, SuNongYunApi.JOB_INFO.url, "672339203207".equals(sortieTask.getSn()));
                return ZhiBaoYunTaskUploader.getRecode(apiUploadResponse, requestBody, "作业信息推送接口");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    //7.5地块信息推送接口
    public RecodeTask uploadJobLand(SortieTask sortieTask) {
        try {
            if (!StringUtils.isEmpty(sortieTask.getGeoJson())) {
                // 1. 创建 jobPlot 数组中的单个作业对象
                JSONObject jobPlotItem = new JSONObject();
                jobPlotItem.put("droneId", sortieTask.getSn());
                jobPlotItem.put("flySorties", sortieTask.getSortieNo());
                jobPlotItem.put("jobDate", sdf2.format(sortieTask.getStartTime()));
                jobPlotItem.put("plotArea", sortieTask.getSize() * 0.0015);
                jobPlotItem.put("missionType", "0".equals(sortieTask.getOptMode()) ? "01" : "02");
                jobPlotItem.put("cropsType", 00);
                if (StringUtils.isNotEmpty(sortieTask.getPositionInfo())) {
                    Map<String, String> map = AddressUtils.parseChineseAddress(sortieTask.getPositionInfo());
                    jobPlotItem.put("workProvince", map.getOrDefault("province", "江苏省"));
                    jobPlotItem.put("workCity", map.getOrDefault("city", "盐城市"));
                    jobPlotItem.put("workCounty", map.getOrDefault("country", "东台市"));
                    jobPlotItem.put("workTown", map.getOrDefault("town", "东台镇"));
                    jobPlotItem.put("workPlace", sortieTask.getPositionInfo() == null ? "江苏省盐城市东台市东台镇" : sortieTask.getPositionInfo());
                }
                List<double[]> doubles = generateDronePath(sortieTask.getGeoJson(), sortieTask.getStartTime(), sortieTask.getEndTime());
                if (!doubles.isEmpty()) {
                    Gson gson = new Gson();
                    jobPlotItem.put("plotBoundary", gson.toJson(doubles));
                }
                jobPlotItem.put("jobStartTime", sdf.format(sortieTask.getStartTime()));
                jobPlotItem.put("jobEndTime", sdf.format(sortieTask.getEndTime()));
                jobPlotItem.put("jobWidth", 3);

                // 2. 创建 jobPlot JSON 数组
                JSONArray jobPlotArray = new JSONArray();
                jobPlotArray.put(jobPlotItem);

                // 3. 创建最外层的 JSON 对象
                JSONObject requestBody = new JSONObject();
                requestBody.put("jobPlot", jobPlotArray); // 嵌套数组
                ApiUploadResponse apiUploadResponse = commonUpload(requestBody, SuNongYunApi.JOB_LAND.url, "672339203207".equals(sortieTask.getSn()));
                return ZhiBaoYunTaskUploader.getRecode(apiUploadResponse, requestBody, "地块信息推送接口");
            }
        } catch (Exception e) {
            e.printStackTrace();

        }
        return null;
    }

    //7.6轨迹信息推送接口
    public RecodeTask uploadDroneTrace(SortieTask sortieTask, List<String> strings) {
        try {
//            if (!StringUtils.isEmpty(sortieTask.getPath())) {
//                List<String> strings = UAesUtil.downloadAndParseFile(sortieTask.getPath());
                if (!strings.isEmpty()) {
                    List<JSONObject> traceJson = AESUtil.getJsonObjects(strings);
                    LocalDateTime startTime = sortieTask.getStartTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
                    LocalDateTime endTime = sortieTask.getEndTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
                    long totalMillis = Duration.between(startTime, endTime).toMillis();
                    double intervalMillis = (double) totalMillis / ((traceJson.size()==1?2:traceJson.size()) - 1);
                    JSONArray droneTraceArray = new JSONArray();
                    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                    for (int i = 0; i < traceJson.size(); i++) {
                        JSONObject osd = traceJson.get(i);
                        // 计算当前时间点
                        LocalDateTime currentTime = startTime.plus(Math.round(i * intervalMillis), ChronoUnit.MILLIS);
                        // 确保最后一个时间点不超过 endTime
                        if (currentTime.isAfter(endTime)) {
                            currentTime = endTime;
                        }
                        JSONObject tracePoint = new JSONObject();
                        tracePoint.put("sTime", currentTime.format(formatter));
                        tracePoint.put("pTime", currentTime.format(formatter));
                        tracePoint.put("isWork", 0);
                        tracePoint.put("lon", osd.get("lon"));
                        tracePoint.put("lat", osd.get("lat"));
                        tracePoint.put("heightSea", osd.get("relativeAlt"));
                        tracePoint.put("heading", osd.get("heading"));
                        tracePoint.put("horizontalVelocity", osd.getDouble("vx"));
                        tracePoint.put("geocentricVelocity", osd.getDouble("vz"));
                        JSONObject droneState = new JSONObject();
                        droneState.put("totalVolt", 0);
                        droneState.put("totalCurr", 0);
                        droneState.put("pumpSpeed", 0);
                        droneState.put("residualDosage", 0);
                        droneState.put("batSoc", 0);
                        tracePoint.put("droneState", droneState);
                        droneTraceArray.put(tracePoint);
                    }

                    JSONObject requestBody = new JSONObject();
                    requestBody.put("droneId", sortieTask.getSn());
                    requestBody.put("flySorties", sortieTask.getSortieNo());
                    requestBody.put("orgName", "LHFJ");
                    if ("672339203207".equals(sortieTask.getSn()))
                        requestBody.put("orgName", "SZLF");
                    requestBody.put("droneTraceInfo", droneTraceArray);
                    ApiUploadResponse apiUploadResponse = commonUpload(requestBody, SuNongYunApi.TRACE.url, "672339203207".equals(sortieTask.getSn()));
                    return ZhiBaoYunTaskUploader.getRecode(apiUploadResponse, requestBody, "轨迹信息推送接口");
                }
//            }
        } catch(Exception e){
            log.error("轨迹信息接口调用失败: ", e);
        }
        return null;
    }

    //7.7图像/视频数据推送接口
    public ApiUploadResponse uploadJobImage(DroneResponse droneResponse) {
        try {
            JSONObject imgInfo = new JSONObject();
            imgInfo.put("droneId", droneResponse.getDroneId());
            imgInfo.put("flySorties", droneResponse.getSortieList().get(3).getSortieNo());
            imgInfo.put("pTime", droneResponse.getSortieList().get(3).getEndTime());
            imgInfo.put("imgLen", "");
            imgInfo.put("lon", droneResponse.getOsd().getLongitude()==0?droneResponse.getOsd().getHomeLocation().getLongitude():droneResponse.getOsd().getLongitude());
            imgInfo.put("lat", droneResponse.getOsd().getLatitude()==0?droneResponse.getOsd().getHomeLocation().getLatitude():droneResponse.getOsd().getLatitude());
            imgInfo.put("jobWidth", 3);
            imgInfo.put("heightSea", droneResponse.getOsd().getHeight());
            imgInfo.put("heading", droneResponse.getOsd().getHeading());
            imgInfo.put("velh", droneResponse.getOsd().getGs());
            imgInfo.put("velup", droneResponse.getOsd().getVs());
            imgInfo.put("heightCrop", droneResponse.getOsd().getAltitude());
//            System.out.println("imgInfo： " + imgInfo.toString());
//            String s = convertToBase64("C:\\Users\\92517\\Desktop\\1749022381129.jpg");
            imgInfo.put("imgCtx", ""); // 实际使用时替换为真实的Base64编码字符串

            // 2. 创建 jobImg JSON 数组
            JSONArray jobImgArray = new JSONArray();
            jobImgArray.put(imgInfo);

            // 3. 创建最外层的 JSON 对象
            JSONObject requestBody = new JSONObject();
            log.info("请求RequestJson： " + requestBody.toString());
            requestBody.put("jobImg", jobImgArray); // 嵌套图片信息数组
            return commonUpload(requestBody, SuNongYunApi.IMAGE.url, "672339203207".equals(droneResponse.getDroneId()));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public String convertToBase64(String filePath) throws Exception {
        byte[] imageBytes = Files.readAllBytes(Paths.get(filePath));
        return Base64.getEncoder().encodeToString(imageBytes);
    }

    public String getNum() {
        Random random = new Random();
        int randomNumber = 100000 + random.nextInt(900000);
        Date now = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String timestamp = sdf.format(now);
        return timestamp + randomNumber;
    }

    public static List<double[]> generateDronePath(
            String geoJson,
            Date startTime,
            Date endTime) {

        ObjectMapper mapper = new ObjectMapper();
        JsonNode root = null;
        try {
            root = mapper.readTree(geoJson);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
        // 验证是否为FeatureCollection
        if (!"FeatureCollection".equals(root.get("type").asText())) {
            throw new IllegalArgumentException("不是有效的FeatureCollection类型GeoJSON");
        }
        List<double[]> coordinates = new ArrayList<>();
        // 遍历features数组
        JsonNode features = root.get("features");
        if (features.isArray()) {
            for (JsonNode feature : features) {
                if ("land".equals(feature.get("id").asText())) {
                    // 提取coordinates
                    JsonNode coordsNode = feature.get("geometry").get("coordinates");
                    int pointCount = coordsNode.size();
                    long start = startTime.getTime(); // 转为毫秒级时间戳
                    long end = endTime.getTime();
                    long totalDuration = end - start;
                    long interval = pointCount > 1 ? totalDuration / (pointCount - 1) : 0;
                    for (int i = 0; i < pointCount; i++) {
                        JsonNode pointNode = coordsNode.get(i);
                        if (pointNode == null || !pointNode.isArray() || pointNode.size() < 2) {
                            continue; // 跳过无效数据
                        }

                        double lon = pointNode.get(0).asDouble();
                        double lat = pointNode.get(1).asDouble();
                        long timestamp = start + (i * interval);
                        coordinates.add(new double[]{lon, lat, timestamp});
                    }
                    // 确保最后一个点的时间戳是精确的结束时间
                    if (pointCount > 1 && !coordinates.isEmpty()) {
                        coordinates.get(coordinates.size() - 1)[2] = end;
                    }
                }
            }
        }
        return coordinates;
    }

    /**
     * 通用上传方法
     * @param requestBody 请求体JSON对象
     * @param apiUrl 接口URL
     * @return UploadResponse 包含流水号、响应数据、URL和状态码
     */
    private ApiUploadResponse commonUpload(JSONObject requestBody, String apiUrl, Boolean flag) {
        try {
            if (TOKEN==null)
                getSuNongYunToken();
            // 生成流水号并放入请求体
            String type = "LHFJ";
            if (flag)
                type = "SZLF";
            String serialNumber = type + getNum();
            requestBody.put("token", TOKEN);
            requestBody.put("serialNumber", serialNumber);

            log.info("请求RequestJson： {}", requestBody.toString());
            Response post = HttpUtils.getPost(requestBody, apiUrl);
            String responseInfo = "URL: " + post.request().url();
            String responseBody = post.body().string();
            JSONObject jsonBody = new JSONObject(responseBody);
            log.info("返回ResponseJson： {}", responseBody);
            if (post.code() != 200)
                getSuNongYunToken();
            if ("500".equals(jsonBody.get("code").toString()))
                return new ApiUploadResponse(serialNumber, responseBody, responseInfo, 500);

            return new ApiUploadResponse(serialNumber, responseBody, responseInfo, post.code());
        } catch (Exception e) {
            log.error("接口调用失败: {}", apiUrl, e);
            return new ApiUploadResponse(null, e.getMessage(), apiUrl, 500);
        }
    }
}